﻿
using EmperialApps.WeatherSpark.Data;
using System;
using System.Windows;
using System.Windows.Media;

namespace EmperialApps.WeatherSpark {

    /// <summary>Contains helper methods for displaying visuals.</summary>
    public static class Display {

        /// <summary>Converts a color to an ARGB value.</summary>
        public static Color ToColor( this uint value ) {
            return Color.FromArgb(
                (byte)(value >> 24),
                (byte)(value >> 16),
                (byte)(value >> 8),
                (byte)(value >> 0) );
        }

        /// <summary>Converts an ARGB value to a color.</summary>
        public static uint FromColor( this Color color ) {
            return (uint)(color.A << 24)
                 | (uint)(color.R << 16)
                 | (uint)(color.G << 8)
                 | (uint)(color.B << 0);
        }


        /// <summary>Creates a rectangle.</summary>
        public static PathFigure CreateRectangleFigure( double left, double right, double top, double bottom ) {
            var start = new Point( left, top );
            var segment = new PolyLineSegment {
                Points = {
                    new Point( right, top ),
                    new Point( right, bottom ),
                    new Point( left, bottom )
                }
            };
            return new PathFigure { StartPoint = start, Segments = { segment } };
        }


        /// <summary>Updates the clip mask for the night background to match the specified temperature data.</summary>
        public static void ClipNightBackground(
            PathGeometry clip, Coordinate location, DateTimeOffset temperatureStart, DataValues temperature,
            Scale timeScale, Scale temperatureScale, bool showExtremesUsingNight, DateTimeOffset? timeScaleStart = null ) {

            DateTimeOffset date = temperatureStart.GetDateOffset( );
            DateTimeOffset endDate = temperatureStart.AddHours( temperature.Count * temperature.Interval );
            DateTimeOffset calculationStart = timeScaleStart ?? temperatureStart;

            var scaleExtremes = Pair.Create( temperatureScale.Minimum, temperatureScale.Maximum );
            while( date < endDate ) {
                DateTimeOffset midnight = date.AddDays( 1 );
                var daylight = Ephemerides.CalculateDaylight( location, date );
                var extremes =
                    showExtremesUsingNight
                        ? temperature.TryGetExtremeValues( temperatureStart, date ) ?? scaleExtremes
                        : scaleExtremes;

                double low = temperatureScale.ToScreen( extremes.Item1 - 0.5 );
                double high = temperatureScale.ToScreen( extremes.Item2 + 0.5 );

                double begin = timeScale.ToScreen( date.HoursFrom( calculationStart ) );
                double sunrise = timeScale.ToScreen( daylight.Item1.HoursFrom( calculationStart ) );
                double sunset = timeScale.ToScreen( daylight.Item2.HoursFrom( calculationStart ) );
                double end = timeScale.ToScreen( midnight.HoursFrom( calculationStart ) );

                clip.Figures.Add( CreateRectangleFigure( begin, sunrise, low, high ) );
                clip.Figures.Add( CreateRectangleFigure( sunset, end, low, high ) );

                date = end >= timeScale.ScreenSize
                     ? endDate
                     : midnight;
            }
        }

    }

}
